package com.xiaoxi.userserver.service.role.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.xiaoxi.common.constant.enumeration.statuscode.other.CommonEnums;
import com.xiaoxi.common.constant.enumeration.statuscode.user.RoleUserEnums;
import com.xiaoxi.common.exception.BMSException;
import com.xiaoxi.domain.role.BMSRole;
import com.xiaoxi.userserver.domain.dto.role.BMSRoleDTO;
import com.xiaoxi.userserver.domain.vo.role.BMSRoleVO;
import com.xiaoxi.userserver.mapper.role.BMSRoleMapper;
import com.xiaoxi.userserver.service.role.BMSRoleMenuService;
import com.xiaoxi.userserver.service.role.BMSRoleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * @author xiaoxi
 * @version 1.0
 * @date 2022/6/1 16:44
 */
@Service
@Slf4j
public class BMSRoleServiceImpl extends ServiceImpl<BMSRoleMapper, BMSRole> implements BMSRoleService {

    @Resource
    private BMSRoleMapper bmsRoleMapper;

    @Resource
    private BMSRoleMenuService bmsRoleMenuService;

    @Override
    public IPage<BMSRole> getAllRole(BMSRoleDTO bmsRoleDTO, Pageable pageable) {

        IPage<BMSRole> iPage = new Page<>(pageable.getPageNumber(), pageable.getPageSize());

        QueryWrapper<BMSRole> queryWrapper = new QueryWrapper<>();

        if (StringUtils.isNotBlank(bmsRoleDTO.getName())) {
            queryWrapper.like("name", bmsRoleDTO.getName());
        }

        if (Objects.nonNull(bmsRoleDTO.getRoleType())) {
            queryWrapper.like("role_type", bmsRoleDTO.getRoleType());
        }

        return bmsRoleMapper.selectPage(iPage, queryWrapper);

    }

    @Override
    public BMSRoleVO getRoleByRoleId(Long roleId) throws BMSException {

        // 角色详情
        BMSRole bmsRole = bmsRoleMapper.selectById(roleId);
        if (Objects.isNull(bmsRole)) {
            throw new BMSException(RoleUserEnums.INCORRECT_ROLE_ID);
        }

        // 菜单
        List<Long> roleMenuList = bmsRoleMenuService.getRoleMenuListByRoleId(bmsRole.getId());

        BMSRoleVO bmsRoleVO = new BMSRoleVO();
        BeanUtils.copyProperties(bmsRole, bmsRoleVO);

        bmsRoleVO.setRoleMenuIdList(roleMenuList);

        return bmsRoleVO;
    }

    @Override
    @Transactional(rollbackFor = BMSException.class)
    public void updateRole(BMSRoleVO bmsRoleVO) throws BMSException {

        if (Objects.isNull(bmsRoleVO.getVersion())) {
            throw new BMSException(CommonEnums.PLEASE_SEND_THE_VERSION);
        }

        if (checkRoleName(bmsRoleVO.getName(), bmsRoleVO.getId())) {
            throw new BMSException(RoleUserEnums.ROLE_REGISTERED);
        }

        // 防止有人传递 假id
        BMSRole role = bmsRoleMapper.selectById(bmsRoleVO.getId());
        if (Objects.isNull(role)) {
            throw new BMSException(RoleUserEnums.INCORRECT_ROLE_ID);
        }

        BMSRole bmsRole = new BMSRole();
        BeanUtils.copyProperties(bmsRoleVO, bmsRole);

        int num = bmsRoleMapper.updateById(bmsRole);

        if (num == 0) {
            throw new BMSException(CommonEnums.INFORMATION_OUT_OF_DATE);
        }

        bmsRoleMenuService.updateRoleMenu(bmsRole.getId(), bmsRoleVO.getRoleMenuIdList());

    }

    @Override
    @Transactional(rollbackFor = BMSException.class)
    public void createRole(BMSRoleVO bmsRoleVO) throws BMSException {

        if (checkRoleName(bmsRoleVO.getName(), null)) {
            throw new BMSException(RoleUserEnums.ROLE_REGISTERED);
        }

        BMSRole bmsRole = new BMSRole();
        bmsRole.setId(bmsRoleVO.getId());
        bmsRole.setName(bmsRoleVO.getName());
        bmsRole.setRoleType(bmsRoleVO.getRoleType());
        bmsRole.setIcon(bmsRoleVO.getIcon());

        bmsRoleMapper.insert(bmsRole);

        bmsRoleMenuService.addRoleMenuByRoleId(bmsRole.getId(), bmsRoleVO.getRoleMenuIdList());

    }

    @Override
    public Boolean checkRoleName(String roleName, Long roleId) {

        QueryWrapper<BMSRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", roleName);
        if (Objects.nonNull(roleId)) {
            queryWrapper.ne("id", roleId);
        }
        return bmsRoleMapper.selectCount(queryWrapper) != 0;

    }

    @Override
    public Boolean checkRoleIdListValid(List<Long> roleIds) {
        QueryWrapper<BMSRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", roleIds);
        List<BMSRole> bmsRoleList = bmsRoleMapper.selectList(queryWrapper);
        return bmsRoleList.size() == roleIds.size();
    }
}
